#include <iostream>
#include <string>
#include <memory>
#include <map>

// 抽象表达式
class AbstractExpression {
public:
    virtual bool interpret(const std::map<std::string, bool>& context) = 0;
    virtual ~AbstractExpression() {}
};

// 终结符表达式
class TerminalExpression : public AbstractExpression {
private:
    std::string variable;
public:
    TerminalExpression(const std::string& variable) : variable(variable) {}
    bool interpret(const std::map<std::string, bool>& context) override {
        return context.at(variable);
    }
};

// 非终结符表达式：AND
class AndExpression : public AbstractExpression {
private:
    std::shared_ptr<AbstractExpression> expr1;
    std::shared_ptr<AbstractExpression> expr2;
public:
    AndExpression(std::shared_ptr<AbstractExpression> expr1, std::shared_ptr<AbstractExpression> expr2)
        : expr1(expr1), expr2(expr2) {}
    bool interpret(const std::map<std::string, bool>& context) override {
        return expr1->interpret(context) && expr2->interpret(context);
    }
};

// 非终结符表达式：OR
class OrExpression : public AbstractExpression {
private:
    std::shared_ptr<AbstractExpression> expr1;
    std::shared_ptr<AbstractExpression> expr2;
public:
    OrExpression(std::shared_ptr<AbstractExpression> expr1, std::shared_ptr<AbstractExpression> expr2)
        : expr1(expr1), expr2(expr2) {}
    bool interpret(const std::map<std::string, bool>& context) override {
        return expr1->interpret(context) || expr2->interpret(context);
    }
};

// 客户（client）构建表达式
std::shared_ptr<AbstractExpression> buildExpressionTree() {
    // 上下文：用户变量定义
    std::shared_ptr<AbstractExpression> expr1 = std::make_shared<TerminalExpression>("X");
    std::shared_ptr<AbstractExpression> expr2 = std::make_shared<TerminalExpression>("Y");
    std::shared_ptr<AbstractExpression> expr3 = std::make_shared<AndExpression>(expr1, expr2);
    return std::make_shared<OrExpression>(expr3, std::make_shared<TerminalExpression>("Z"));
}

int main() {
    std::shared_ptr<AbstractExpression> expression = buildExpressionTree();
    std::map<std::string, bool> context = {{"X", true}, {"Y", false}, {"Z", true}};
    bool result = expression->interpret(context);
    std::cout << "The result is " << (result ? "true" : "false") << std::endl;
    return 0;
}